#include "inputitemdelegate.h"
#include "tablewidgetsdelegate.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "idlethread.h"

#include "configs.h"
#include "mbcommunication.h"
#include <QDebug>
#include <QSerialPortInfo>
#include <QSqlQuery>
#include <QSystemTrayIcon>
#include <QtSql/QSqlDatabase>
#include <QObject>


uint16_t *tab_reg;
//QSqlDatabase database;
twSerialDelegate *gate_name;
twSerialDelegate *gate_enname;
twSerialDelegate *gate_baud;
twSerialDelegate *gate_parity;
twSerialDelegate *gate_data;
twSerialDelegate *gate_stop;
twNumberDelegate *gate_num;
QStringList allports;
QStringList enports;

QList<SerialConfigs *> serials;
QList<InputConfigs *> inputs;
QList<OutputConfigs *> outputs;
QList<MBCommunication *> mbcs;



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QSystemTrayIcon *trayIcon= new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(QString::fromUtf8(":/image/connect.ico")));
    trayIcon->setToolTip(tr("Modbus"));
    connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_IconActivated(QSystemTrayIcon::ActivationReason)));
    trayIcon->show();

    up_c.addFile(QString::fromUtf8(":/image/update_c.ico"));
    up_b.addFile(QString::fromUtf8(":/image/update_b.ico"));

    down_c.addFile(QString::fromUtf8(":/image/down_c.ico"));
    down_b.addFile(QString::fromUtf8(":/image/down_b.ico"));

//    database = QSqlDatabase::addDatabase("QSQLITE");
//    database.setHostName("localhost");
//    database.setDatabaseName("memtest.db");

    SerialConfigs::loadFromSerials("mbconfig.ini",&serials);
    InputConfigs::loadFromInputs("mbconfig.ini",&inputs);
    OutputConfigs::loadFromOutputs("mbconfig.ini",&outputs);

    memset(this->maindatabase,-10,sizeof(this->maindatabase));

    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        allports<<info.portName();
    }

    foreach(SerialConfigs *sc,serials)
    {
        enports<<sc->getSerialName();
    }

    gate_name=new twSerialDelegate(twSerialDelegate::serialname,allports);
    gate_enname=new twSerialDelegate(twSerialDelegate::serialname,enports);
    gate_baud=new twSerialDelegate(twSerialDelegate::serialbaud);
    gate_parity=new twSerialDelegate(twSerialDelegate::serialparity);
    gate_data=new twSerialDelegate(twSerialDelegate::serialdata);
    gate_stop=new twSerialDelegate(twSerialDelegate::serialstop);
    gate_num=new twNumberDelegate();

    ui->tw_serial->setItemDelegateForColumn(0,gate_name);
    ui->tw_serial->setItemDelegateForColumn(1,gate_baud);
    ui->tw_serial->setItemDelegateForColumn(2,gate_data);
    ui->tw_serial->setItemDelegateForColumn(3,gate_parity);
    ui->tw_serial->setItemDelegateForColumn(4,gate_stop);

    ui->tw_input->setItemDelegateForColumn(0,gate_enname);
    ui->tw_input->setItemDelegateForColumn(1,gate_num);
    ui->tw_input->setItemDelegateForColumn(2,gate_num);
    ui->tw_input->setItemDelegateForColumn(3,gate_num);
    ui->tw_input->setItemDelegateForColumn(4,gate_num);

    ui->tw_output->setItemDelegateForColumn(0,gate_enname);
    ui->tw_output->setItemDelegateForColumn(1,gate_num);
    ui->tw_output->setItemDelegateForColumn(2,gate_num);
    ui->tw_output->setItemDelegateForColumn(3,gate_num);
    ui->tw_output->setItemDelegateForColumn(4,gate_num);

    SerialConfigs::loadFromSerials("mbconfig.ini",ui->tw_serial,&serials);
    InputConfigs::loadFromInputs("mbconfig.ini",ui->tw_input,&inputs);
    OutputConfigs::loadFromOutputs("mbconfig.ini",ui->tw_output,&outputs);

    appStart();

}

MainWindow::~MainWindow()
{
    free(tab_reg);
    delete ui;
}
modbus_t *mb;
modbus_mapping_t *mb_mapping;
int rc;

void MainWindow::on_pushButton_clicked()
{
    QString create_sql = "create table value_tab1 (id int primary key, value int)";
    QSqlQuery sql_query;
    mb=modbus_new_rtu("COM7",9600,'N',8,1);
    modbus_set_slave(mb,1);
    modbus_connect(mb);
    struct timeval t;
    t.tv_sec=1;
    t.tv_usec=0;   //设置modbus超时时间为1000毫秒
    modbus_set_response_timeout(mb, &t);
    int regs=modbus_read_registers(mb,0,10,tab_reg);
    qDebug()<<tab_reg[0]<<tab_reg[1]<<tab_reg[2]<<tab_reg[3];
    modbus_close(mb);
    modbus_free(mb);
    qDebug()<<sql_query.prepare(create_sql);
    sql_query.exec();

}


void MainWindow::on_pushButton_2_clicked()
{
    mb=modbus_new_rtu("COM7",9600,'N',8,1);
    modbus_set_slave(mb,1);
    modbus_connect(mb);
    mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0,
                                    MODBUS_MAX_READ_REGISTERS, 0);
    for(;;) {
        uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];

        rc = modbus_receive(mb, query);
        if (rc >= 0)
        {
            mb_mapping->tab_registers[0]=1234;
            mb_mapping->tab_registers[1]=2345;
            qDebug()<<rc;
            modbus_reply(mb, query, 30, mb_mapping);
        } else
        {
            /* Connection closed by the client or server */
            break;
        }
    }
}

void MainWindow::on_pb_dataclear_clicked()
{

}

void MainWindow::on_IconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason)
    {
    case QSystemTrayIcon::Trigger :
        setWindowState(Qt::WindowActive);
        activateWindow();
        break;
    default:
        break;
    }
}


void MainWindow::on_pb_InputDel_clicked()
{
    ui->tw_input->removeRow(ui->tw_input->currentRow());
}

void MainWindow::on_pb_InputAdd_clicked()
{
    int rows=ui->tw_input->rowCount();
    if(ui->tw_input->item(rows-1,0)||ui->tw_input->rowCount()==0)
        ui->tw_input->insertRow(ui->tw_input->rowCount());
}

void MainWindow::on_pb_serialdel_clicked()
{
    ui->tw_serial->removeRow(ui->tw_serial->currentRow());
}

void MainWindow::on_pb_serialadd_clicked()
{
    int rows=ui->tw_serial->rowCount();
    if(ui->tw_serial->item(rows-1,0)||ui->tw_serial->rowCount()==0)
        ui->tw_serial->insertRow(ui->tw_serial->rowCount());
}


void MainWindow::on_pb_serialconfirm_clicked()
{
    SerialConfigs::saveToSerials("mbconfig.ini",ui->tw_serial);
    qApp->exit(733);
}

void MainWindow::on_pb_InputConfirm_clicked()
{
    InputConfigs::saveToInputs("mbconfig.ini",ui->tw_input);
}

void MainWindow::on_pb_OuputConfirm_clicked()
{
    OutputConfigs::saveToOutputs("mbconfig.ini",ui->tw_output);
}

void MainWindow::on_pb_OutputAdd_clicked()
{
    int rows=ui->tw_output->rowCount();
    if(ui->tw_output->item(rows-1,0)||ui->tw_output->rowCount()==0)
        ui->tw_output->insertRow(ui->tw_output->rowCount());
}

void MainWindow::on_pb_OutputDel_clicked()
{
    ui->tw_output->removeRow(ui->tw_output->currentRow());
}




idleThread *ith;
void MainWindow::on_pb_start_clicked()
{
    appStart();
}

void MainWindow::on_pb_stop_clicked()
{
    appStop();
}

void MainWindow::stateOutputToggle(QListWidgetItem *listIcon)
{

}

void MainWindow::changeIcon(QListWidgetItem *listicon, QIcon icon)
{
    listicon->setIcon(icon);
}

void MainWindow::stateInputToggle(QListWidgetItem *listIcon)
{
    //qDebug()<<listIcon->icon().themeName();
    //qDebug()<<listIcon->icon().themeName().compare("up_c");
//    if(listIcon->icon().themeName().compare("up_c")>=0)
//    {
//        up_b.setThemeName("up_b");
//        listIcon->setIcon(up_b);
//        //listIcon->icon().swap(up_b);
//    }
//    else
//    {
//        up_c.setThemeName("up_c");
//        listIcon->setIcon(up_c);
//        //listIcon->icon().swap(up_c);
//    }
}

void MainWindow::appStart()
{
    int id=0;

    SerialConfigs::loadFromSerials("mbconfig.ini",&serials);
    InputConfigs::loadFromInputs("mbconfig.ini",&inputs);
    OutputConfigs::loadFromOutputs("mbconfig.ini",&outputs);

    ui->lw_state->clear();

    for(int i=0;i<inputs.count();i++)
    {
        QString name=inputs[i]->getInputSerialName();
        int index=enports.indexOf(name);
        if(index<0)
            continue;
        serials[index]->insertIntoInputs(inputs[i]);
        QListWidgetItem* qwi = new QListWidgetItem(QIcon(QString::fromUtf8(":/image/empty.ico")),
                                                   inputs[i]->getInputSerialName()
                                                   +"/ID:"+QString::number(inputs[i]->getInputSlaveID())
                                                   +QString("/Addr:%1-%2").arg(inputs[i]->getInputSaveAddress(),4,10,QLatin1Char('0'))
                                                   .arg(inputs[i]->getInputSaveAddress()+inputs[i]->getInputDataLength(),4,10,QLatin1Char('0')),
                                                   ui->lw_state
                                                   );
        inputs[i]->listIcon=qwi;
        ui->lw_state->insertItem(0,qwi);
        connect(inputs[i],SIGNAL(stateToggle(QListWidgetItem*)),this,SLOT(stateInputToggle(QListWidgetItem*)));
    }

    for(int i=0;i<outputs.count();i++)
    {
        QString name=outputs[i]->getOutputSerialName();
        int index=enports.indexOf(name);
        if(index<0)
            continue;
        serials[index]->insertIntoOutputs(outputs[i]);
        QListWidgetItem* qwi = new QListWidgetItem(QIcon(QString::fromUtf8(":/image/empty.ico")),
                                                   outputs[i]->getOutputSerialName()
                                                   +"/ID:"+QString::number(outputs[i]->getOutputSlaveID())
                                                   +QString("/Addr:%1-%2").arg(outputs[i]->getOutputDataAddress(),4,10,QLatin1Char('0'))
                                                   .arg(outputs[i]->getOutputDataAddress()+outputs[i]->getOutputDataLength(),4,10,QLatin1Char('0')),
                                                   ui->lw_state
                                                   );
        outputs[i]->listIcon=qwi;
        ui->lw_state->insertItem(0,qwi);
    }

    for(int i=0;i<serials.count();i++)
    {
        MBCommunication::COMType tcom;
        if(serials[i]->inputs.count()>0)
            tcom=MBCommunication::COMInput;
        else if(serials[i]->outputs.count()>0)
            tcom=MBCommunication::COMOutput;
        else
            continue;
        MBCommunication *mbc=new MBCommunication(tcom,serials[i],maindatabase);
        mbc->start();
        mbcs<<mbc;
    }



    if(ith==NULL)
    {
        ith=new idleThread(ui->tw_view,this->maindatabase);
        ith->setInputs(&inputs);
        ith->setOutputs(&outputs);
        connect(ith,SIGNAL(changeIcon(QListWidgetItem*,QIcon)),this,SLOT(changeIcon(QListWidgetItem*,QIcon)));
    }
    ith->start();
    ui->pb_start->setEnabled(false);
    ui->pb_stop->setEnabled(true);

}

void MainWindow::appStop()
{
    for(int i=0;i<mbcs.count();i++)
    {
        mbcs[i]->terminate();
        delete(mbcs[i]);
    }
    mbcs.clear();
    ith->quit();
    ui->pb_stop->setEnabled(false);
    ui->pb_start->setEnabled(true);
}
